//
//  CollectionViewBaseVM.swift
//  jhf
//
//  Created by 计海峰 on 2021/10/13.
//  Copyright © 2021 CocoaPods. All rights reserved.
//

import UIKit
import Kingfisher
import RxSwift
import RxDataSources

// MARK: - collection 控制器
open class CollectionViewBaseVM: NSObject, CollectionViewModelProtocol {
    
    // MARK: - 属性
    /// cvc 是否需要长按
    public var isLongPressGesture: Bool = false
    /// 长按手势
    public lazy var panGes: UILongPressGestureRecognizer! = {
        let panGes = UILongPressGestureRecognizer(target: self, action: #selector(handlelongGesture(_:)))
        panGes.isEnabled = true
        panGes.minimumPressDuration = 0.2 // 触发长按事件时间为：秒
        return panGes
    }()
    
    /// file data key
    public var fileKey: String = "file"
    
    /// 自定义 flow layout
    public var flowLayout: UICollectionViewFlowLayout?
    
    /// 自定义 移动item
    public var moveItem: CollectionViewSectionedDataSource<SectionM>.MoveItem?
    
    // MARK: - 高度通知
    /// cvc height observe
    public var cellHeightSubject = BehaviorSubject<CGFloat>(value: 0.0)
    
    // MARK: - 生成datasource
    public func configDataSource() -> RxCollectionViewSectionedReloadDataSource<SectionM> {
        if let ds = dataSource {
            return ds
        }
        
        let ds = RxCollectionViewSectionedReloadDataSource<SectionM>(
            configureCell: { dataSource, cv, indexPath, item in
                let cell = cv.dequeueReusableCell(indexPath: indexPath, cls: item.cellCls())
                // 绑定数据
                cell.bindTo(item)
                // 背景色
                if let bgColor = item.bgColor {
                    cell.backgroundColor = bgColor
                }
                return cell
            },
            moveItem: { dataSource, sourceIndexPath, destinationIndexPath in
                
                if let move = self.moveItem {
                    move(dataSource, sourceIndexPath, destinationIndexPath)
                    return
                }
                
                guard var section = self.sections[safe: sourceIndexPath.section] else { return }
                guard let item = section.items[safe: sourceIndexPath.row] else { return }
                section.items.remove(at: sourceIndexPath.row)
            
                self.sections[sourceIndexPath.section] = CollectionViewBaseVM.orderItems(section)
                
                guard var toSection = self.sections[safe: destinationIndexPath.section] else { return }
                toSection.items.insert(item, at: destinationIndexPath.row)
                self.sections[destinationIndexPath.section] = CollectionViewBaseVM.orderItems(toSection)
                
            },
            canMoveItemAtIndexPath: { dataSource, indexPath in
                return true
            }
        )
        dataSource = ds
        return dataSource!
    }
    
    // MARK: - 排序 items
    /// - Returns: 排序之后的 section
    private static func orderItems(_ sec: SectionM) -> SectionM {
        
        var section = sec
        let section_first_items = section.items.filter { model in
            if let item = model as? CollectionCellLongPressConfigProtocol {
                return item.isLocationFirst
            }
            return false
        }
        
        let section_last_items = section.items.filter { model in
            if let item = model as? CollectionCellLongPressConfigProtocol {
                return item.isLocationLast
            }
            return false
        }
        
       section.items.removeAll { model in
            if let item = model as? CollectionCellLongPressConfigProtocol {
                return item.isLocationFirst || item.isLocationLast
            }
            return false
        }
        
        section.items = section_first_items + section.items + section_last_items
        
        return section
        
    }
    
    
    // MARK: - 显示图片
    @objc func showImages(_ info: Any) {
        guard let item = info as? BindKeyProtocol else { return }
        guard let indexPath = byKeySearchIndexPath(self, key: item.bindKey())  else { return }
        guard let section = self.sections[safe: indexPath.section] else { return }
        
        let items: [Any?] = section.items.map {
            guard let control = $0.model as? ViewControlProtocol else { return nil }
            if !control.isShow { return nil }
            if let imageSource = control.imageSource {
                return imageSource
            }
            if let url = control.url {
                return url
            }
            if let name = control.imageName {
                return name
            }
            return nil
        }.filter {
            $0 != nil
        }
        let currentIdx = section.items.firstIndex {
            if let info = $0 as? BindKeyProtocol {
                return item.bindKey() == info.bindKey()
            }
            return false
        } ?? 0
        showPhotosBrowser(items as [Any], index: currentIdx)
    }
    
    // MARK: - 通过key搜索tablle的indexpath
    func byKeySearchIndexPath(_ parent: CollectionViewModelProtocol, key: String) -> IndexPath? {
        for (sectionIdx, section) in parent.sections.enumerated() {
            for (index, model) in section.items.enumerated() {
                if let info = model as? BindKeyProtocol {
                    if info.bindKey() == key {
                        return IndexPath(row: index, section: sectionIdx)
                    }
                }
            }
        }
        return nil
    }
    
    // MARK: - 长按
    //  监听手势，并设置其允许移动cell和交换资源
    @objc func handlelongGesture(_ ges: UILongPressGestureRecognizer) {
        guard let collectionView = ges.view as? UICollectionView else { return }
        let location = ges.location(in: collectionView)
        // 当手指的位置不在collectionView的cell范围内时为nil
        let notSureIndexPath = collectionView.indexPathForItem(at: location)
        switch ges.state {
        case .began:
            if let indexPath = notSureIndexPath { // 获取到的indexPath是有效的, 可以放心使用
                // 判断是不是不要长按
                if !self.isLongPressGesture {
                    return
                }
                // if indexPath.row == 0 || indexPath.section != 0 { return }
                let cell = collectionView.cellForItem(at: indexPath)!
                collectionView.bringSubviewToFront(cell)
                collectionView.beginInteractiveMovementForItem(at: indexPath)
            }
        case .changed:
           collectionView.updateInteractiveMovementTargetPosition(location)
        case .ended :
            collectionView.endInteractiveMovement()
        default:
            collectionView.cancelInteractiveMovement()
        }
    }
    
    
}
